package cn.kwq.project_manger.dtoUtils;

import cn.dev33.satoken.annotation.SaIgnore;
import cn.hutool.core.util.DesensitizedUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.kwq.project_manger.pojo.*;
import cn.kwq.project_manger.pojo.dto.PageDto;
import cn.kwq.project_manger.pojo.dto.ResProJDto;
import cn.kwq.project_manger.repostitory.ProjectTagRepository;
import cn.kwq.project_manger.repostitory.TagRepository;
import cn.kwq.project_manger.service.FilesService;
import com.querydsl.jpa.impl.JPAQueryFactory;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * Created with IntelliJ IDEA.
 *
 * @Author: kwq
 * @Date: 2023/02/23/0:05
 * @Description: 抽离业务对象封装代码
 */
@Data
@Component
@Slf4j
public class ResProJDtoUtils {

    @Autowired
    JPAQueryFactory jpaQueryFactory;

    @Autowired
    ProjectTagRepository projectTagRepository;

    @Autowired
    TagRepository tagRepository;

    @Autowired
    FilesService filesService;


    /**
     * 标签名字集合 新增项目使用
     * 转换为标签id集合（表里面没有的就新增 实现前端自动新增标签）
     */
    @Transactional
    public Long getTagIdByName(String tagName){
        QTag tag=QTag.tag;
        //查出tag表有当前标签
        Long tagID = jpaQueryFactory
                .select(tag.tagId)
                .from(tag)
                .where(tag.tagName.eq(tagName))
                .where(tag.tagType.eq(0))
                .fetchOne();
        //没有就新增加这个标签
        if (tagID==null){
            log.info("标签 ["+tagName+"] 不存在，开始新增");

            Tag tagSave = tagRepository.save(Tag
                    .builder()
                    .tagType(0)
                    .tagName(tagName)
                    .build());

            String tagNameSave = tagSave.getTagName();
            log.info("新增 ["+tagNameSave+"] 标签成功");


            tagID = jpaQueryFactory
                    .select(tag.tagId)
                    .from(tag)
                    .where(tag.tagName.eq(tagName))
                    .where(tag.tagType.eq(0))
                    .fetchOne();
        }
        return  tagID;
    }


    /**
     * 标签名字集合
     * 转换为标签id集合（但不新增）
     */
    @Transactional
    public Long getTagIdButNotAdd(String tagName){
        QTag tag=QTag.tag;
        //查出tag表有当前标签
        Long tagID = jpaQueryFactory
                .select(tag.tagId)
                .from(tag)
                .where(tag.tagName.eq(tagName))
                .where(tag.tagType.eq(0))
                .fetchOne();
        //没有就新增加这个标签
        if (tagID==null){
            throw new RuntimeException(tagName+" 标签不存在");
        }
        return  tagID;
    }

    //绑定项目的标签

    /**
     * 将标签绑定至指定项目
     * @param list 标签list
     * @param projectId 项目id
     */
    @Transactional
    public void bindTags(List<Long> list,Long projectId){
        log.info("执行项目绑定标签操作");
        //先删除原来已有标签
        QProjectTag pt=QProjectTag.projectTag;
        long execute = jpaQueryFactory.delete(pt)
                .where(pt.projectId.eq(projectId))
                .execute();
        for (Long tagId:list){
            if (execute!=0){
                log.info(projectId+"号项目进行更新");
                log.info(projectId+"号项目解除"+execute+"标签绑定");
            }else {
                log.info(projectId+"号项目进行绑定标签");
            }

            projectTagRepository.save(ProjectTag
                    .builder().tagId(tagId)
                    .projectId(projectId)
                    .build());

            log.info(projectId+"号项目绑定标签成功");
        }
    }


    /**
     * 转换成分页对象 查询使用
     * @param fetch 正常对象集合
     * @param total 总数
     * @param type 转换类型
     * @return  分页对象
     */
    @SaIgnore
    //总数和project生成分页返回对象
    public PageDto ProJ2PageDto(List<Project> fetch, Long total, Integer type) {
        List<ResProJDto> collect=null;
        if (type==0){
            collect = fetch.stream()
                    .map(item -> {
                                try {
                                    return ResProJDto
                                            .builder()
                                            .project(TuoMin(item))//脱敏
                                            .tags(getTags(item.getProjectId()))
                                            .imgUrl(getImgUrl(item.getProjectId()))
                                            .likes(countLikes(item.getProjectId()))
                                            .build();
                                } catch (Exception e) {
                                    throw new RuntimeException(e.getMessage());
                                }
                            }
                    )
                    .collect(Collectors.toList());
        }else{
            collect  = fetch.stream()
                    .map(item -> {
                                try {
                                    return ResProJDto
                                            .builder()
                                            .project(TuoMin(item))
                                            .tags(null)//比赛没有标签
                                            .imgUrl(getImgUrl(item.getProjectId()))
                                            .likes(countLikes(item.getProjectId()))
                                            .build();
                                } catch (Exception e) {
                                    throw new RuntimeException(e.getMessage());
                                }
                            }
                    )
                    .collect(Collectors.toList());
        }


        return PageDto.builder()
                .pageDate(collect)
                .total(total)
                .build();
    }



    /**
     * 查询总喜欢数
     * @param projectId 项目id
     * @return like数量
     */
    @Transactional
    @SaIgnore
    public Long countLikes(Long projectId){
        QLikes likes=QLikes.likes;
        return
                jpaQueryFactory.select(likes.likeId.count())
                        .from(likes)
                        .where(likes.projectId.eq(projectId))
                        .fetchOne();

    }

    /**
     * 获取该项目的相关图片url
     * @param projectId 项目id
     * @return 图片url集合
     * @throws Exception 调用minio错误
     */
    @SaIgnore
    public List<String> getImgUrl(Long projectId) throws Exception {
        List<String> imgUrlByProJId = filesService.getImgUrlByProJId(projectId);
        if(imgUrlByProJId!=null&&imgUrlByProJId.get(0)==null){
            return null;
        }
        return imgUrlByProJId;
    }


    /**
     * 数据脱敏
     */
    @SaIgnore
    public Project TuoMin(Project project){

        String phone = project.getConnectPublisher();
        String createName = project.getCreateName();

        //将对象克隆一份返回，避免触发鉴权校验
        Project clone = ObjectUtil.clone(project);

        Optional.ofNullable(phone).ifPresent(item-> clone.setConnectPublisher(DesensitizedUtil.mobilePhone(item)));
        Optional.ofNullable(createName).ifPresent(item-> clone.setCreateName(DesensitizedUtil.chineseName(item)));
        return clone;
    }

    /**
     * 通过projectId查找他的tag集合
     */
    @SaIgnore
    public List<String> getTags(Long projectId){
//        QProject proj=QProject.project;
        QTag tag=QTag.tag;
        QProjectTag con=QProjectTag.projectTag;

        List<String> fetch = jpaQueryFactory.select(tag.tagName)
                .from(tag).leftJoin(con).on(con.tagId.eq(tag.tagId))
//                .leftJoin(proj).on(con.projectId.eq(proj.projectId))
                .where(con.projectId.eq(projectId))
                .fetch();

        System.out.println(fetch);
        if (fetch==null||fetch.isEmpty()||fetch.get(0)==null){
            return null;
        }
        return fetch;

    }
}
